package com.syxp.pda.service.detail.impl;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.transaction.annotation.Transactional;

import com.syxp.pda.core.bean.FieldBean;
import com.syxp.pda.core.command.QueryFilter;
import com.syxp.pda.core.util.Operation;
import com.syxp.pda.core.util.TimeFormatUtil;
import com.syxp.pda.dao.detail.CheckPlanDetailDao;
import com.syxp.pda.entity.detail.CheckPlanDetail;
import com.syxp.pda.entity.detail.CheckPlanDetailUtil;
import com.syxp.pda.entity.detail.ExamCountBean;
import com.syxp.pda.service.detail.ExamManagerService;

@Transactional
public class ExamManagerServiceImpl implements ExamManagerService {

	private CheckPlanDetailDao checkPlanDetailDao;

	public CheckPlanDetailDao getCheckPlanDetailDao() {
		return checkPlanDetailDao;
	}

	public void setCheckPlanDetailDao(CheckPlanDetailDao checkPlanDetailDao) {
		this.checkPlanDetailDao = checkPlanDetailDao;
	}

	private DecimalFormat df = new DecimalFormat("###.0") ;

	@Override
	public List<ExamCountBean> examCount(List<FieldBean> fields) {
		QueryFilter checkCountFilter = new QueryFilter();
		QueryFilter noCheckCountFilter = new QueryFilter();
		QueryFilter unCheckCountFilter = new QueryFilter();
		List<FieldBean> projections = new ArrayList<FieldBean>();
		for (FieldBean field : fields) {
			checkCountFilter.addFilter(field);
			noCheckCountFilter.addFilter(field);
			unCheckCountFilter.addFilter(field);
		}

		projections.add(new FieldBean("lineName", null, Operation.COUNT));
		projections.add(new FieldBean("lineName", null, Operation.GROUP));

		checkCountFilter.addFilter(new FieldBean("isDownload", (byte) 0,
				Operation.EQUAL));
		checkCountFilter.addProject(projections);
		List<Object[]> checkCountList = checkPlanDetailDao.getAll(
				checkCountFilter, "dutyAll");

		noCheckCountFilter.addFilter(new FieldBean("isDownload", (byte) 0,
				Operation.EQUAL));
		noCheckCountFilter.addFilter(new FieldBean("deviceRunStateCode", 2,
				Operation.EQUAL));
		noCheckCountFilter.addProject(projections);
		List<Object[]> noCheckCountList = checkPlanDetailDao.getAll(
				noCheckCountFilter, "dutyAll");

		unCheckCountFilter.addFilter(new FieldBean("isDownload", (byte) 0,
				Operation.EQUAL));
		unCheckCountFilter.addFilter(new FieldBean("chkResultChar", null,
				Operation.ISNULL));
		unCheckCountFilter.addFilter(new FieldBean("chkResultValue", null,
				Operation.ISNULL));
		unCheckCountFilter.addProject(projections);
		List<Object[]> unCheckCountList = checkPlanDetailDao.getAll(
				unCheckCountFilter, "dutyAll");

		return buildExamCount(checkCountList, noCheckCountList,
				unCheckCountList);
	}

	public List<CheckPlanDetail> unCheckList(List<FieldBean> fields) {

		QueryFilter queryFilter = new QueryFilter();
		for (FieldBean field : fields) {
			queryFilter.addFilter(field);
		}
		queryFilter.addFilter(new FieldBean("isDownload", (byte) 0,
				Operation.EQUAL));
		queryFilter.addFilter(new FieldBean("chkResultChar",null,Operation.ISNULL)) ;
		queryFilter.addFilter(new FieldBean("chkResultValue",null,Operation.ISNULL)) ;
		List<String> order = new ArrayList<String>() ;
		order.add("lineName") ;
		order.add("pda_CHKDatetime") ;
		List<CheckPlanDetail> details = checkPlanDetailDao.getAll(queryFilter,
				"dutyAll");
		return details;
	}

	public List<Object[]> unCheckCount(List<FieldBean> fields) {
		QueryFilter queryFilter = new QueryFilter();
		for (FieldBean field : fields) {
			queryFilter.addFilter(field);
		}
		queryFilter.addFilter(new FieldBean("isDownload", (byte) 0,
				Operation.EQUAL));
		queryFilter.addFilter(new FieldBean("chkResultChar",null,Operation.ISNULL)) ;
		queryFilter.addFilter(new FieldBean("chkResultValue",null,Operation.ISNULL)) ;
		List<FieldBean> projections = new ArrayList<FieldBean>();
		projections.add(new FieldBean("lineName", null, Operation.COUNT));
		projections.add(new FieldBean("lineName", null, Operation.GROUP));
		queryFilter.addProject(projections);
		List<Object[]> list = checkPlanDetailDao.getAll(queryFilter,
			"dutyAll");
		return list ;
		
	}
	
	public List<Object[]> placeCount(List<FieldBean> fields) {

		String baseSql = "SELECT  A.PlanName, A.LineName, "
			+ "A.ZoneName, A.DutyName, A.ClaName, A.TurnOrder, "
			+ "A.Start_PDA_CHKDateTime, A.End_PDA_CHKDateTime, "
			+ "OnDuty =  CASE WHEN Sum(A.OnDuty) > 0 THEN 1 ELSE"
			+ " 0  END, A.UserName, A.OperatorCode FROM (SELECT "
			+ "*, OnDuty =  CASE WHEN "
			+ "CHKResultValue IS NOT NULL THEN 1"
			+ " WHEN CHKResultChar IS NOT NULL "
			+ "AND CHKResultChar <> '' "
			+ "THEN 1 ELSE 0 END FROM EL_CHKPlanDetail WHERE "
			+ "IsDownload = 0 "+"fields" 
			+ ") AS A GROUP BY A.PlanName, A.LineName, A.ZoneName,"
			+ " A.DutyName, A.ClaName, A.TurnOrder, A.Start_PDA_CHKDateTime, "
			+ "A.End_PDA_CHKDateTime, A.UserName, A.OperatorCode "
			+ "ORDER BY Start_PDA_CHKDateTime ASC";
		String fieldStr = "" ;
		for(FieldBean field : fields) {
			fieldStr=fieldStr + " and " +field.getProperty() ;
			if(StringUtils.equals(field.getOperation(), Operation.EQUAL)) {
				fieldStr+=" = ? " ;
			}else if(StringUtils.equals(field.getOperation(), Operation.GE)) {
				fieldStr+=" >= ? " ;
			}else if(StringUtils.equals(field.getOperation(), Operation.LE)) {
				fieldStr+=" <= ? " ;
			}
		}
		baseSql = baseSql.replaceAll("fields", fieldStr) ;
		return checkPlanDetailDao.excuteSql(baseSql, fields) ;
		
	}

	public List<CheckPlanDetailUtil> workCount(List<FieldBean> fields) {
		QueryFilter queryFilter = new QueryFilter() ;
		for(FieldBean field : fields) {
			queryFilter.addFilter(field) ;
		}
		queryFilter.addFilter(new FieldBean("pda_CHKDatetime",null,Operation.ISNOTNULL)) ;
		List<String> order = new ArrayList<String>() ;
		queryFilter.addFilter(new FieldBean("isDownload",(byte)0,Operation.EQUAL)) ;
		order.add("pda_CHKDatetime") ;
		queryFilter.setOrderProperty(order) ;
		List<CheckPlanDetail> details = checkPlanDetailDao.getAll(queryFilter, "dutyAll") ;
		List<CheckPlanDetailUtil> detailUtils = new ArrayList<CheckPlanDetailUtil>() ;
		long workTime = 0 ;
		Calendar c = Calendar.getInstance() ;
		for(int i=0 ; i<details.size() ; i++) {
			if((i+1)< details.size()){
				CheckPlanDetailUtil detailTemp = new CheckPlanDetailUtil() ;
				c.clear() ;
				if(details.get(i).getStart_PDA_CHKDateTime()
						.equals(details.get(i+1).getStart_PDA_CHKDateTime())) {
					c.setTimeInMillis(c.getTimeInMillis()+workTime) ;
					detailTemp.setCheckPlanDetail(details.get(i)) ;
					detailTemp.setWorkTime(TimeFormatUtil.formatWorkTime(c.getTime())) ;
					workTime = details.get(i+1).getPda_CHKDatetime().getTime()-
						details.get(i).getPda_CHKDatetime().getTime();
				}else{
					workTime = 0 ;
					c.setTimeInMillis(c.getTimeInMillis()+workTime) ;
					detailTemp.setCheckPlanDetail(details.get(i)) ;
					detailTemp.setWorkTime(TimeFormatUtil.formatWorkTime(c.getTime())) ;
				}
				detailUtils.add(detailTemp) ;
			}
		}
		return detailUtils ;
	}
	
	private List<ExamCountBean> buildExamCount(List<Object[]> checkCountList,
			List<Object[]> noCheckCountList, List<Object[]> unCheckCountList) {
		List<ExamCountBean> list = new ArrayList<ExamCountBean>();
		for (Object[] object : checkCountList) {
			ExamCountBean examCount = new ExamCountBean();
			examCount.setLineName(String.valueOf(object[1]));
			examCount.setCheckCount(String.valueOf(object[0]));
			for (Object[] noObject : noCheckCountList) {
				if (StringUtils.equals(String.valueOf(object[1]),
						String.valueOf(noObject[1]))) {
					examCount.setNoCheckCount(String.valueOf(noObject[0]));
				}
			}
			for (Object[] unObject : unCheckCountList) {
				if (StringUtils.equals(String.valueOf(object[1]),
						String.valueOf(unObject[1]))) {
					examCount.setUnCheckCount(String.valueOf(unObject[0]));
					
				}
			}
			examCount.setCheckedCount(String.valueOf(Integer.parseInt(examCount
					.getCheckCount())
					- Integer.parseInt(examCount.getNoCheckCount())
					- Integer.parseInt(examCount.getUnCheckCount())));
			examCount.setUnCheckRatio(df.format( Float.parseFloat(examCount.getUnCheckCount())/Float.
					parseFloat(examCount.getCheckCount())*100)+"%") ;
			examCount.setCheckRatio(df.format( (Float.parseFloat(examCount.getCheckedCount())/Float.
					parseFloat(examCount.getCheckCount()))*100)+"%") ;
			examCount.setNoCheckRatio(df.format( (Float.parseFloat(examCount.getNoCheckCount())/Float.
					parseFloat(examCount.getCheckCount()))*100)+"%") ;
			
			list.add(examCount);

		}
		return list;
	}

	@Override
	public List<CheckPlanDetail> lineCount(List<FieldBean> fields) {
		
		return null;
	}

}
